import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { fetchDeptList } from '@/api/system/dept'
import { fetchStaffList } from '@/api/system/staff'
import { fetchRoleList } from '@/api/system/role'


// 按你的字段定义
export interface Department {
  dept_code: string
  dept_name: string
}

export interface Saler {
  id: string
  name: string
  type: string
  industry: string
  pm: string
  department: string
  is_supervisor: string
}

export interface Customer {
  id: string
  customer_name: string
  customer_code: string
  division: string
  salesperson: string
}

export interface Role {
  id: number
  name: string
  status?: boolean
  desc?: string | null
}

// 数据集合类型
export type SystemPayload = {
  departments?: Department[]
  salers?: Saler[]
  customers?: Customer[]
  roles?: Role[]
  [key: string]: any
}

type LoaderFn<T> = () => Promise<T[]>

export const useSystemStore = defineStore(
  'systemStore',
  () => {
    // 缓存与时间戳
    const data = ref<SystemPayload>({})
    const lastLoadedAt = ref<Record<string, number>>({})

    // 计算属性
    const getAll = computed(() => data.value)
    const getDepartments = computed(() => data.value.departments || [])
    const getSalers = computed(() => data.value.salers || [])
    const getRoles = computed(() => data.value.roles || [])
    const getCustomers = computed(() => data.value.customers || [])

    // 基础操作
    const setData = (payload: SystemPayload) => {
      data.value = payload || {}
      const now = Date.now()
      Object.keys(data.value).forEach((k) => (lastLoadedAt.value[k] = now))
    }

    const mergeData = (payload: SystemPayload) => {
      const merged: SystemPayload = { ...data.value }
      Object.keys(payload || {}).forEach((key) => {
        merged[key] = payload[key]
        lastLoadedAt.value[key] = Date.now()
      })
      data.value = merged
    }

    const clear = () => {
      data.value = {}
      lastLoadedAt.value = {}
    }

    // 新鲜度与按需保证
    const getLastLoadedAt = (type?: string): number | Record<string, number> => {
      if (type) return lastLoadedAt.value[type] || 0
      return lastLoadedAt.value
    }

    const needsRefresh = (type: string, ttlMs = 10 * 60 * 1000): boolean => {
      const ts = lastLoadedAt.value[type] || 0
      return !data.value[type] || Date.now() - ts > ttlMs
    }

    /**
     * ensure：按需加载指定数据类型
     * @param loaders 键到异步加载函数的映射，例如 { departments: fetchDepartments }
     * @param types 可选，需要加载的键数组，不传表示按 loaders 的所有键
     * @param options ttlMs、force
     */
    const ensure = async (
      loaders: Record<string, LoaderFn<any>>,
      types?: string[],
      options?: { ttlMs?: number; force?: boolean }
    ): Promise<void> => {
      const ttl = options?.ttlMs ?? 10 * 60 * 1000
      const force = !!options?.force
      const typeList = Array.isArray(types) && types.length ? types : Object.keys(loaders)
      const need = typeList.filter((t) => force || needsRefresh(t, ttl))
      if (!need.length) return

      const result: SystemPayload = {}
      for (const key of need) {
        const loader = loaders[key]
        if (typeof loader === 'function') {
          result[key] = await loader()
        }
      }
      mergeData(result)
    }

    // ===== 接入正式 API 的内置加载器 =====
    const PAGE_SIZE = 100

    const fetchDepartments = async (): Promise<Department[]> => {
      let current = 1
      const size = PAGE_SIZE
      const all: Department[] = []

      while (true) {
        const res = await fetchDeptList({ current, size })
        const chunk = Array.isArray(res.items) ? res.items : []
        all.push(
          ...chunk.map((d) => ({ dept_code: d.dept_code, dept_name: d.dept_name }))
        )
        const pages = res.pages ?? Math.ceil((res.total || 0) / (res.size || size))
        if (current >= pages || chunk.length === 0) break
        current += 1
      }

      return all
    }

    const fetchSalers = async (): Promise<Saler[]> => {
      let current = 1
      const size = PAGE_SIZE
      const all: Saler[] = []

      while (true) {
        const res = await fetchStaffList({ current, size })
        const chunk = Array.isArray(res.items) ? res.items : []
        all.push(
          ...chunk.map((s) => ({
            id: String(s.id ?? ''),
            name: s.name,
            type: s.type,
            industry: s.industry ?? '',
            pm: s.pm,
            department: s.department,
            is_supervisor: s.is_supervisor,
          }))
        )
        const pages = res.pages ?? Math.ceil((res.total || 0) / (res.size || size))
        if (current >= pages || chunk.length === 0) break
        current += 1
      }

      return all
    }

    const fetchRoles = async (): Promise<Role[]> => {
      let current = 1
      const size = PAGE_SIZE
      const all: Role[] = []

      while (true) {
        const res = await fetchRoleList({ current, size })
        const chunk = Array.isArray(res.items) ? res.items : []
        all.push(
          ...chunk.map((r) => ({
            id: r.id ?? 0,
            name: r.name,
            status: r.status,
            desc: r.desc ?? null
          }))
        )
        const pages = res.pages ?? Math.ceil((res.total || 0) / (res.size || size))
        if (current >= pages || chunk.length === 0) break
        current += 1
      }

      return all
    }

    /**
     * 便捷初始化：按需加载内置的 system 数据
     * @param types 可选：['departments', 'salers']
     * @param options ttlMs、force
     */
    const init = async (
      types?: string[],
      options?: { ttlMs?: number; force?: boolean }
    ): Promise<void> => {
      const loaders: Record<string, LoaderFn<any>> = {
        departments: fetchDepartments,
        salers: fetchSalers,
        roles: fetchRoles
      }
      await ensure(loaders, types, options)
    }

    return {
      data,
      lastLoadedAt,
      getAll,
      getDepartments,
      getSalers,
      getRoles,
      getCustomers,
      setData,
      mergeData,
      clear,
      getLastLoadedAt,
      needsRefresh,
      ensure,
      init
    }
  },
  {
    persist: {
      key: 'system',
      storage: localStorage
    }
  }
)